package UILayer;
import java.util.Scanner;

import CtrLayer.StockCtr;
import ModelLayer.CurrentAccount;

/**
 * Write a description of class StockUI here.
 * This class represents the user interface of the Stock
 * managing system
 * @author (Georgi Georgiev) 
 * @version (10.12.2013)
 */
public class StockUI
{
    private StockCtr stock_ctr;
    /**
     * Constructor for objects of class StockUI
     */
    public StockUI()
    {
       stock_ctr = new StockCtr();
    }

    /**********************************************MENUS**********************************************************/
    
    /**
     * The main menu of the StockUI which can manage the Product(CRUD)
     * From here you can choose to add, find, view category, edit and delete product,
     * basic CRUD operations.
     */
    public void stock_menu()
    {
        boolean exit = false;
        boolean is_employee = CurrentAccount.give_rank().equals("employee");
        while(!(exit))
        {
            int choice = write_stock_menu(is_employee);
            if(is_employee)
            {
                switch(choice)
                {
                    case 1 :    add_product();
                                break;
                    case 2 :    find_product();
                                break;
                    case 3 :    display_category();
                                break;
                    case 4 :    display_by_group_nr();
                                break;
                    case 5 :    edit_product();
                                break;
                    case 6 :    delete_product();
                                break;
                    default:    exit = true;
                                stock_ctr.save_data();
                                break;
                }
            }
            else
            {
                switch(choice)
                {
                    case 1 :    add_product();
                                break;
                    case 2 :    find_product();
                                break;
                    case 3 :    display_category();
                                break;
                    case 4 :    display_by_group_nr();
                                break;
                    case 5 :    edit_product();
                                break;
                    case 6 :    delete_product();
                                break;
                    case 7 :    manage_unfinished_products();
                                break;
                    case 8 :    display_products_that_need_restocking();
                                break;
                    default:    exit = true;
                                stock_ctr.save_data();
                                break;
                }
            }

        }
        System.out.println("\f");           // Needs checking if necessary
    }
    
    /**
     * Sub-Menu to edit product(option 4 in the main menu)
     */
    private void edit_product_menu(String art_nr)
    {
        boolean exit = false;
        boolean is_manager = (!(CurrentAccount.give_rank().equals("employee")));
        boolean is_kb;
        while(!(exit))
        {
            is_kb = stock_ctr.is_kitchen_bathroom_product(art_nr);
            int choice = write_edit_product_menu(is_manager, is_kb);
            if(!(is_manager))
            {
                if(is_kb)
                {
                    switch(choice)
                    {
                        case 1 :    edit_name(art_nr);
                                    break;
                        case 2 :    edit_category(art_nr);
                                    break;
                        case 3 :    edit_department(art_nr);
                                    break;
                        case 4 :    edit_pieces_in_palette(art_nr);
                                    break;
                        case 5 :    edit_quantity(art_nr);
                                    break;
                        case 6 :    edit_maximum_amount(art_nr);
                                    break;
                        case 7 :    edit_minimum_amount(art_nr);
                                    break;   
                        case 8 :    edit_group_nr(art_nr);
                                    break;
                        default:    exit = true;
                                    stock_ctr.save_data();
                                    break;
                    }
                }
                else
                {
                    switch(choice)
                    {
                        case 1 :    edit_name(art_nr);
                                    break;
                        case 2 :    edit_category(art_nr);
                                    break;
                        case 3 :    edit_department(art_nr);
                                    break;
                        case 4 :    edit_pieces_in_palette(art_nr);
                                    break;
                        case 5 :    edit_quantity(art_nr);
                                    break;
                        case 6 :    edit_maximum_amount(art_nr);
                                    break;
                        case 7 :    edit_minimum_amount(art_nr);
                                    break;   
                        default:    exit = true;
                                    stock_ctr.save_data();
                                    break;
                    }
                }
            }
            else
            {
                if(is_kb)
                {
                    switch(choice)
                    {
                        case 1 :    edit_name(art_nr);
                                    break;
                        case 2 :    edit_category(art_nr);
                                    break;
                        case 3 :    edit_department(art_nr);
                                    break;
                        case 4 :    edit_pieces_in_palette(art_nr);
                                    break;
                        case 5 :    edit_quantity(art_nr);
                                    break;
                        case 6 :    edit_maximum_amount(art_nr);
                                    break;
                        case 7 :    edit_minimum_amount(art_nr);
                                    break;
                        case 8 :    edit_group_nr(art_nr);
                                    break;  
                        case 9 :    edit_amount_qualified_for_discount(art_nr);
                                    break;
                        case 10 :   edit_discount(art_nr);
                                    break;
                        case 11 :   edit_price(art_nr);
                                    break;  
                        case 12 :   edit_price_for_palette(art_nr);
                                    break;            
                        default:    exit = true;
                                    stock_ctr.save_data();
                                    break;
                    }
                }
                else
                {
                    switch(choice)
                    {
                        case 1 :    edit_name(art_nr);
                                    break;
                        case 2 :    edit_category(art_nr);
                                    break;
                        case 3 :    edit_department(art_nr);
                                    break;
                        case 4 :    edit_pieces_in_palette(art_nr);
                                    break;
                        case 5 :    edit_quantity(art_nr);
                                    break;
                        case 6 :    edit_maximum_amount(art_nr);
                                    break;
                        case 7 :    edit_minimum_amount(art_nr);
                                    break;
                        case 8 :    edit_amount_qualified_for_discount(art_nr);
                                    break;  
                        case 9 :    edit_discount(art_nr);
                                    break;
                        case 10 :   edit_price(art_nr);
                                    break;  
                        case 11 :   edit_price_for_palette(art_nr);
                                    break;
                        default:    exit = true;
                                    stock_ctr.save_data();
                                    break;
                    }
                }
            }

        }
        System.out.println("\f");           // Needs checking if necessary
    }    
    
    /*********************************************************MENU WRITERS*******************************************************/
    
    /**
     * Text user menu which represents the options in the main menu of Product.
     */
    private int write_stock_menu(boolean is_employee)
    {
        System.out.println("\f***PRODUCT MENU***");
        System.out.println("Press (1) to add a product.");
        System.out.println("Press (2) to find a product.");
        System.out.println("Press (3) to find a product by a specific category.");
        System.out.println("Press (4) to display products by their group number.");
        System.out.println("Press (5) to edit a product.");
        System.out.println("Press (6) to delete a product.");
        if(!(is_employee))
        {
            System.out.println("Press (7) manage unfinished products.");
            System.out.println("Press (8) to display all products that need to be restocked.");
        }
        System.out.println("Press any other number to exit.");
        return int_input();
    }
    
    /**
     * Text user menu which represents the options in the sub-menu of Product.
     */
    private int write_edit_product_menu(boolean is_manager, boolean is_kb)
    {
        int i = 8;
        System.out.println("\f***EDIT PRODUCT MENU***");
        System.out.println("Press (1) to change product name.");
        System.out.println("Press (2) to change product category.");
        System.out.println("Press (3) to change product department/location.");
        System.out.println("Press (4) to change the amount of products in palette.");
        System.out.println("Press (5) to change the amount of products in stock.");
        System.out.println("Press (6) to change product maximum amount in stock.");
        System.out.println("Press (7) to change product minimum amount in stock.");
        if(is_kb)
        {
            i = 9;
            System.out.println("Press (8) to change the group number of the product.");
        }
        if(is_manager)
        {
            System.out.println("Press (" + i + ") to change amount of product qualified for discount.");
            System.out.println("Press (" + (i + 1) + ") to change the discount.");
            System.out.println("Press (" + (i + 2) + ") to change product price."); 
            System.out.println("Press (" + (i + 3) + ") to change product price for palette."); 
        }
        System.out.println("Press any other number to exit.");
        return int_input();
    }    
    
    /****************************************************PRODUCT MENU METHODS****************************************************/
    
    /**
     * 
     */
    private void add_product()
    {
        Scanner keyboard = new Scanner(System.in);
        String name;
        while(stock_ctr.is_such_name(name = input_name()))
        {
            System.out.println("This name is already used in the system. You have to provide a unique name for the product");
        }
        String category = input_category();
        String department = input_department();
        double price = 0;
        double price_for_palette = 0;
        int maximum_amount;
        int minimum_amount = input_minimum_amount();
        double discount = 0;
        
        while((maximum_amount = input_maximum_amount()) <= minimum_amount)
        {
            System.out.println("The maximum amount of product in the stock must be greater than a minimum one.");
        }
        
        int pieces_in_palette;
        while(((pieces_in_palette = input_pieces_in_palette()) > maximum_amount))
        {
            System.out.println("The amount of products in a palette cannot be higher than a maximum amount of product in the stock.");
        }
        
        int quantity;
        while((quantity = input_quantity()) > maximum_amount)
        {
            System.out.println("The quantity cannot be higher than a maximum amount of product in the stock.");
        }
        
        int amount_qualified_for_discount = 0;
        String group_nr = "0";
        if(department.equals("KB"))
        {
            group_nr = input_group_nr();
        }
        
        if(!(CurrentAccount.give_rank().equals("employee")))
        {
            price = input_price();
            
            if(pieces_in_palette != 0)
            {
                while((price_for_palette = input_price_for_palette()) < price)
                {
                    System.out.println("Price for palette cannot be lower than a price of a single product");
                }
            }
            
            while((amount_qualified_for_discount = input_amount_qualified_for_discount()) > maximum_amount)
            {
                System.out.println("The amount qualified for discount cannot be higher than a maximum amount of product in the stock.");
            }
            
            if(amount_qualified_for_discount != 0)
            {
               discount = input_discount();
            }
        }
        
        if(stock_ctr.add_product(name, category, department, price, price_for_palette, pieces_in_palette, quantity, maximum_amount, minimum_amount, amount_qualified_for_discount, group_nr, discount))
        {
            System.out.println("You have successfully added a product");
        } else
        {
            System.out.println("Error");
        }
        wait_for_input();
    }
    
    /**
     * 
     */
    private void find_product()
    {
        String input;
        String type_of_input;
        
        while((input = check(input_art_nr_or_name())).equals("nothing")){}
        
        if(!(input.equals("0")))
        {
            if(stock_ctr.is_product_unfinished(input))
            {
                System.out.println("This product is unfinished!\n\n");
            }
            System.out.println(stock_ctr.find_product_by_art_nr(input));
            wait_for_input();
        }   
    }
    
    /**
     * Menu option to display all products in a category.
     */
    private void display_category()
    {
        System.out.println("Enter category: ");
        String category = string_input();
        System.out.println(stock_ctr.find_products_by_category(category));
        wait_for_input();
    }
    
    private void display_by_group_nr()
    {
        String group_nr;
        while(!(stock_ctr.is_such_group_nr(group_nr = input_group_nr_search())))
        {
            System.out.println("There is no such group.");
        }
        if(!(group_nr .equals("0")))
        {
            System.out.println(stock_ctr.display_by_group_nr(group_nr));
        }
        wait_for_input();
    }
    
    
    private void manage_unfinished_products()
    {
        boolean wrong = true;
        int choice;
        while(wrong)
        {
            System.out.println("\fPress (1) to display all unfinished products.");
            System.out.println("Press (2) to finish adding a product.");
            System.out.println("Press any other number to exit.");
            choice = int_input();
            switch(choice)
            {
                case 1 :    display_unfinished_products();
                            break;
                case 2 :    finish_product();
                            break;
                default:    wrong = false;
                            break;
            }
        }
    }
    
    private void display_unfinished_products()
    {
        System.out.println(stock_ctr.display_unfinished_products());
        wait_for_input();
    }
    
    private void display_products_that_need_restocking()
    {
        System.out.println(stock_ctr.display_products_that_need_restocking());
        wait_for_input();
    }
    
    private void finish_product()
    {
        String art_nr = "";
        boolean wrong = true;
        while (wrong)
        {
            if(!(art_nr = check(input_art_nr_or_name())).equals("nothing"))
            {
                if(!(art_nr.equals("0")))
                {
                    if(stock_ctr.is_product_unfinished(art_nr))
                    {
                        wrong = false;
                    }
                    else
                    {
                        System.out.println("This product does not require finishing.");
                    }
                }
                else
                {
                    wrong = false;
                }
            }
        }
        if(!(art_nr.equals("0")))
        {
            edit_price(art_nr);
            edit_price_for_palette(art_nr);
            edit_amount_qualified_for_discount(art_nr);
            edit_discount(art_nr);
        }
    }
    
    /**
     * 
     */
    private void edit_product()
    {
        String art_nr;
        while (((art_nr = check(input_art_nr_or_name())).equals("nothing"))){}
        if(!(art_nr.equals("0")))
        {
            edit_product_menu(art_nr);
        }
    }
    
    /**
     * Menu option to delete product.
     */
    private void delete_product()
    {
        String art_nr;
        while((art_nr = check(input_art_nr_or_name())).equals("nothing")) {}
        
        if(!(art_nr.equals("0")))
        {
            if(stock_ctr.delete_product(art_nr))
            {
                System.out.println("The product was successfully deleted");
            }
        }

    }
    
    /****************************************************EDIT PRODUCT MENU METHODS****************************************************/
    
    /**
     * Method to change the name of the product.
     */
    public void edit_name(String art_nr)
    {
        String name;
        while(stock_ctr.is_such_name(name = input_name()))
        {
            System.out.println("This name is already used in the system. You have to provide a unique name for the product");
        }
        stock_ctr.edit_name(art_nr, name);
        System.out.println("You have successfully changed the name of the product");
        wait_for_input();
    }
    
    /**
     * Method to change product's category.
     */
    public void edit_category(String art_nr)
    {
        stock_ctr.edit_category(art_nr, input_category());
        System.out.println("You have successfully changed the category of the product");
        wait_for_input();
    }

    
    /**
     * Method to change product's location/department.
     */
    public void edit_department(String art_nr)
    {
        stock_ctr.edit_department(art_nr, input_department());
        System.out.println("You have successfully changed the department in which the product is located.");
        wait_for_input();
    }    
    
    /**
     * Method to change product's price (Accessable only by the manager).
     */
    public void edit_price(String art_nr)
    {
        while(!(stock_ctr.edit_price(art_nr, input_price())))
        {
            System.out.println("The price of the product cannot be higher than a price for a palette");
        }
        System.out.println("You have successfully changed the price of the product.");
        wait_for_input();
    }
    
    /**
     * Method to change price for palette (Accessable only by the manager).
     */
    public void edit_price_for_palette(String art_nr)
    {
        stock_ctr.edit_price_for_palette(art_nr, input_price_for_palette());
        System.out.println("You have successfully changed the price of a palette of products.");
        wait_for_input();
    }
    
    /**
     * Method to change the amount of products in a single palette.
     */
    public void edit_pieces_in_palette(String art_nr)
    {
        stock_ctr.edit_pieces_in_palette(art_nr, input_pieces_in_palette());
        System.out.println("You have successfully changed the number of pieces in a palette of products.");
        wait_for_input();
    }
    
    /**
     * Method to change the amount of product in stock.
     */
    public void edit_quantity(String art_nr)
    {
        while(!(stock_ctr.edit_quantity(art_nr, input_quantity())))
        {
             System.out.println("The quantity cannot be higher than a maximum amount of product in the stock.");
        }
        System.out.println("You have successfully changed the quantity of the product");
        wait_for_input();
    }
    
    /**
     * Method to change the maximum amount of product in stock.
     */
    public void edit_maximum_amount(String art_nr)
    {
        while(!(stock_ctr.edit_maximum_amount(art_nr, input_maximum_amount())))
        {
            System.out.println("The maximum amount of product in the stock must be greater than a minimum one.");
        }
        System.out.println("You have successfully changed the maximum amount of the product in stock.");
        wait_for_input();
    }
    
    /**
     * Method to change the minimum amount of product in stock.
     */
    public void edit_minimum_amount(String art_nr)
    {   
        while(!(stock_ctr.edit_minimum_amount(art_nr, input_minimum_amount())))
        {
            System.out.println("The minimum amount of product in the stock must be smaller than a maximum one.");
        }
        System.out.println("You have successfully changed the minimum amount of the product in stock.");
        wait_for_input();
    }
    
    /**
     * Method to change the amount of products to get a discount (Accessable only by the manager).
     */
    public void edit_amount_qualified_for_discount(String art_nr)
    {
        while(!(stock_ctr.edit_amount_qualified_for_discount(art_nr, input_amount_qualified_for_discount())))
        {
            System.out.println("The amount qualified for discount cannot be higher than a maximum amount of product in the stock.");
        }
        System.out.println("You have successfully changed the amount of the product qualified for discount.");
        wait_for_input();
    }    
    
    private void edit_group_nr(String art_nr)
    {
        stock_ctr.edit_group_nr(art_nr, input_group_nr());
        System.out.println("You have successfully changed the group number of the product.");
        wait_for_input();
    }
    
    private void edit_discount(String art_nr)
    {
        stock_ctr.edit_discount(art_nr, input_discount());
        System.out.println("You have successfully changed the discount of the product.");
        wait_for_input();
    }

    /****************************************************OTHER METHODS****************************************************/
    
    /**
     * Method to  take and check the input by the user and also returning it.
     */
    private int int_input()
    {
        int input = 0;
        boolean ok = false;
        Scanner keyboard = new Scanner(System.in);
        while(!(ok))
        {
            try
            {
                input = keyboard.nextInt();
                ok = true;
            }
            catch (Exception e)
            {
                System.out.println("You must provide a valid input.\nYou have to type a number");
                keyboard.nextLine();
            }
        }
        return input;
    }
    
     private double double_input()
    {
        double input = 0;
        boolean ok = false;
        Scanner keyboard = new Scanner(System.in);
        while(!(ok))
        {
            try
            {
                input = keyboard.nextDouble();
                ok = true;
            }
            catch (Exception e)
            {
                System.out.println("You must provide a valid input.\nYou have to type a number");
                keyboard.nextLine();
            }
        }
        return input;
    }
    
    private String string_input()
    {
        Scanner keyboard = new Scanner(System.in);
        return keyboard.nextLine();
    }
    
    /**
     * Method to check the input whether the product exists and if it's searching by the articule number or name.
     */
    private String check(String input)
    {
            if(input.equals("0"))
            {
                return input;
            }
            if(input.matches("[0-9]+"))
            {
                if(!(stock_ctr.does_exist(input)))
                {
                    System.out.println("There is no such product with this articule number.");
                    return "nothing";
                }
                else
                {
                    return input;
                }

            }
            else 
            {
                if(!(stock_ctr.is_such_name(input)))
                {
                    System.out.println("There is no such product with this name.");
                    return "nothing";
                }
                else
                {
                    return stock_ctr.get_art_nr_via_name(input);
                }
            }
        
    }
    
    private boolean is_product_finished(String art_nr)
    {
        return stock_ctr.is_product_unfinished(art_nr);
    }
    
    /****************************************************INPUT METHODS****************************************************/
    
    
    /**
     * Input method for articule number.
     */
    private String input_art_nr()
    {
        System.out.println("Insert articule number: ");
        String art_nr = "" + int_input();
        return art_nr;
    }
    
    /**
     * Input method for name.
     */
    private String input_name()
    {
        System.out.println("Insert name: ");
        return string_input();
    }
    
    private String input_art_nr_or_name()
    {
        System.out.println("Enter articule number or name of a product or type (0) to return: ");
        return string_input();
    }
    
    /**
     * Input method for category.
     */
    private String input_category()
    {
        System.out.println("Insert category: ");
        return string_input();
    }
    
    /**
     * Input method for department.
     */
    private String input_department()
    {
        System.out.println("Insert department.\nType DIY to add it to DIY department.\nType T to add it to Timber department.\nType KB to add it to Kitchen&Bathroom department.");
        String var = "" ;
        while(!((var = string_input()).equals("DIY") || var.equals("T") || var.equals("KB")))
        {
            System.out.println("You inserted incorrect input.\nPlease write DIY for DIY department T for timber department or KB for Kitchen&Bathroom department:");
        }
        return var;
    }
    
    /**
     * Input method for price.
     */
    private double input_price()
    {
        System.out.println("Insert price: ");
        double price;
        while((price = double_input()) <= 0)
        {
            System.out.println("Price must be greater than 0");
        }
        return price;
    }
    
    /**
     * Input method for price of a single palette.
     */
    private double input_price_for_palette()
    {
        System.out.println("Insert price for a palette: ");
        return double_input();
    }
    
    /**
     * Input method for amount of products in palette.
     */
    private int input_pieces_in_palette()
    {
        System.out.println("Insert amount of product in palette.");
        int pieces_in_palette;
        while((pieces_in_palette = int_input()) <= 1)
        {
            System.out.println("Number of pieces of product in a palette must be greater than 1");
        }
        return pieces_in_palette;
    }
    
    /**
     * Input method for the quantity of the product.
     */
    private int input_quantity()
    {
        System.out.println("Insert the quantity of a product: ");
        int quantity;
        while((quantity = int_input()) < 0)
        {
            System.out.println("The quantity of product must be no smaller than 0");
        }
        return quantity;
    }
    
    /**
     * Input method for maximum amount of the product. 
     */
    private int input_maximum_amount()
    {
        System.out.println("Insert maximum amount in stock: ");
        return int_input();
    }
    
    /**
     * Input method for minimum amount of the product.
     */
    private int input_minimum_amount()
    {
        System.out.println("Insert minimum amount in stock: ");
        int minimum_amount;
        while((minimum_amount = int_input()) <= 0)
        {
            System.out.println("The minimum amount of product in the stock must be greater than 0");
        }
        return minimum_amount;
    }

    /**
     * Input method to set the qualified amount of products for a discount.
     */
    private int input_amount_qualified_for_discount()
    {
        System.out.println("Insert amount of product qualified for discount.");
        int amount_qualified_for_discount;
        while((amount_qualified_for_discount = int_input()) <= 0)
        {
            System.out.println("The amount of product qualified for discount in the stock must be greater than 0.");
        }
        return amount_qualified_for_discount;
    }
    
    private String input_group_nr()
    {
        System.out.println("Insert group number of the product.\nIf the product is not part of a group, type (0):");
        String group_nr = "" + int_input();
        return group_nr;
    }
    
    private String input_group_nr_search()
    {
        System.out.println("Insert group number of the product. Type (0) to exit.");
        String group_nr = "" + int_input();
        return group_nr;
    }
    
    private double input_discount()
    {
        boolean ok = true;
        double discount = 0;
        do
        {
            System.out.println("Insert discount in percentages:");
            String del = string_input();
            if (del.endsWith("%"))
            {
                del = del.substring(0, del.length() - 1);
            }
            try
            {
                discount = Double.parseDouble(del);
                if ((discount < 0)||(discount > 100))
                {
                    System.out.println("The discount was not correct, please try again!");
                    ok = false;
                }
                else
                {
                    ok=true;
                }
            }
            catch (Exception e)
            {
                System.out.println("The discount was not correct, please try again!");
                ok=false;
            }
        }
        while (!ok);
        return discount;
    }    
    
    private void wait_for_input()
    {
        System.out.println("\nPRESS ENTER TO CONTINUE\n");
        Scanner keyboard = new Scanner(System.in);
        keyboard.nextLine();
    }
    
}

